package com.sh.filesystem.controller;

import com.google.common.collect.Maps;
import com.sh.filesystem.common.JsonMapper;
import com.sh.filesystem.common.ResultUtil;
import com.sh.filesystem.entity.ShoaFile;
import com.sh.filesystem.enums.ResultEnum;
import com.sh.filesystem.handle.ExceptionHandle;
import com.sh.filesystem.service.FileService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author: he changjie on 2019/2/17
 * @Description:
 */
@RequestMapping("/file")
@RestController
public class FileSystemController {
    private JsonMapper jsonMapper = JsonMapper.INSTANCE;
    @Autowired
    private ExceptionHandle exceptionHandle;
    @Autowired
    private FileService fileService;

    /**
     * 上传文件
     * 新增文件和更新文件共享接口
     * 当id为空时为新增
     * @param file 文件
     * @return
     */
    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    public ResponseEntity fileUpload(@RequestParam("file") MultipartFile file){
        try {
            String filePath = ClassLoader.getSystemResource("").toURI().getPath().substring(1)+"static/file/";
            String fileName=file.getOriginalFilename();
            File locateFile=new File((filePath+fileName).replaceAll("/","\\\\"));
            File dir=new File(filePath.replaceAll("/","\\\\"));
            if(!dir.exists()){
                dir.mkdirs();
            }
            int temp=0;
            while(locateFile.exists()){
                locateFile=new File((filePath+file.getOriginalFilename().substring(0,file.getOriginalFilename().lastIndexOf("."))+temp+++file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."))).replaceAll("/","\\\\"));
            }
            long size = file.getSize();
            file.transferTo(locateFile);
            HashMap<Object, Object> map = Maps.newHashMap();
            map.put("fileSourceName",locateFile.getName());
            map.put("fileSize",String.valueOf(size/1024.0));
            String iconType=locateFile.getName().substring(locateFile.getName().lastIndexOf(".")+1).toLowerCase();
            switch (iconType){
                case "jpg":
                case "jpeg":iconType="jpg";break;
                case "doc":
                case "docx":iconType="word";break;
                case "xls":
                case "xlsx":iconType="excel";break;
                case "ppt":
                case "pptx":iconType="ppt";break;
                case "dwt":
                case "dwg":
                case "dws":
                case "dxf":iconType="cad";break;
                default:break;
            }
            map.put("iconType",iconType);
            return new ResponseEntity(ResultUtil.success(map), HttpStatus.OK);
        } catch (URISyntaxException|IOException e) {
            return new ResponseEntity(exceptionHandle.exceptionGet(e), HttpStatus.OK);
        }
    }

    /**
     * 下载文件
     * @param fileName 文件名称（含后缀）
     * @return
     */
    @RequestMapping(value = "/downFile", method = RequestMethod.GET)
    public ResponseEntity<byte []> fileDownload(@RequestParam("fileName") String fileName) {
        //文件的字节数组
        byte[] body=null;
        // 响应头的文件信息
        String headerValue = null;
        String filePath= null;
        try {
            filePath = ClassLoader.getSystemResource("").toURI().getPath().substring(1)+"static/file/";
            //文件
            File file=new File((filePath+fileName).replaceAll("/","\\\\"));
            if(file.exists()) {
                //防止中文乱码！
                headerValue = String.format("attachment; filename=\"%s\"", java.net.URLEncoder.encode(fileName, "UTF-8"));

                InputStream in = new FileInputStream(file);
                body = new byte[in.available()];
                in.read(body);
                HttpHeaders headers = new HttpHeaders();
                headers.add("Content-Disposition", headerValue);
                headers.add("Content-Type", "application/octet-stream");
                return new ResponseEntity<>(body,headers,HttpStatus.OK);
            }
            return new ResponseEntity(ResultUtil.error(ResultEnum._FAILED), HttpStatus.OK);
        } catch (URISyntaxException | IOException e) {
            return new ResponseEntity(exceptionHandle.exceptionGet(e), HttpStatus.OK);
        }
    }

    /**
     * 添加一个文件
     * @param shoaFile 文件
     * @return
     */
    @RequestMapping(value = "/add",method = RequestMethod.POST)
    public ResponseEntity addFile(@RequestBody ShoaFile shoaFile){
        try {
            int add = fileService.add(shoaFile);
            if(add!=-1){
                return new ResponseEntity(ResultUtil.success(null), HttpStatus.OK);
            }else{
                return new ResponseEntity(ResultUtil.error(ResultEnum._FAILED), HttpStatus.OK);
            }
        } catch (Exception e) {
            return new ResponseEntity(exceptionHandle.exceptionGet(e), HttpStatus.OK);
        }
    }

    /**
     * 删除一个文件
     * @param id 文件ID
     * @return
     */
    @RequestMapping(value = "/delete/{id}",method = RequestMethod.GET)
    public ResponseEntity delFile(@PathVariable String id){
        try {
            int delete = fileService.delete(id);
            if(delete!=-1){
                return new ResponseEntity(ResultUtil.success(null), HttpStatus.OK);
            }else{
                return new ResponseEntity(ResultUtil.error(ResultEnum._FAILED), HttpStatus.OK);
            }
        } catch (Exception e) {
            return new ResponseEntity(exceptionHandle.exceptionGet(e), HttpStatus.OK);
        }
    }

    /**
     * 更新一个文件
     * @param shoaFile 文件
     * @return
     */
    @RequestMapping(value = "/update",method = RequestMethod.POST)
    public ResponseEntity updateFile(@RequestBody ShoaFile shoaFile){
        try {
            int update = fileService.update(shoaFile);
            if(update!=-1){
                return new ResponseEntity(ResultUtil.success(null), HttpStatus.OK);
            }else{
                return new ResponseEntity(ResultUtil.error(ResultEnum._FAILED), HttpStatus.OK);
            }
        } catch (Exception e) {
            return new ResponseEntity(exceptionHandle.exceptionGet(e), HttpStatus.OK);
        }
    }

    /**
     * 拉取一个文件
     * @param id 文件ID
     * @return
     */
    @RequestMapping(value = "/queryOne/{id}",method = RequestMethod.GET)
    public ResponseEntity queryOne(@PathVariable String id){
        try {
            ShoaFile shoaFile = fileService.queryOne(id);
            if(shoaFile!=null){
                return new ResponseEntity(ResultUtil.success(shoaFile), HttpStatus.OK);
            }else{
                return new ResponseEntity(ResultUtil.error(ResultEnum._FAILED), HttpStatus.OK);
            }
        } catch (Exception e) {
            return new ResponseEntity(exceptionHandle.exceptionGet(e), HttpStatus.OK);
        }
    }

    /**
     * 分页
     * 查询所有文件
     * @param params 查询参数（search文件名、currentPage当前页、pageSize页尺寸）
     * @return
     */
    @RequestMapping(value = "/queryAll/{params}",method = RequestMethod.GET)
    public ResponseEntity queryAll(@PathVariable String params){
        try {
            Map fromJson = jsonMapper.fromJson(params, Map.class);
            String search = (String)fromJson.get("search");
            int currentPage = (int)fromJson.get("currentPage");
            int pageSize = (int)fromJson.get("pageSize");
            List<ShoaFile> list = fileService.queryAll(search,currentPage,pageSize);
            if(list!=null){
                HashMap<String, Object> map = Maps.newHashMap();
                map.put("list",list);
                map.put("total",fileService.queryAll(search));
                map.put("currentPage",currentPage);
                map.put("pageSize",pageSize);
                return new ResponseEntity(ResultUtil.success(map), HttpStatus.OK);
            }else{
                return new ResponseEntity(ResultUtil.error(ResultEnum._FAILED), HttpStatus.OK);
            }
        } catch (Exception e) {
            return new ResponseEntity(exceptionHandle.exceptionGet(e), HttpStatus.OK);
        }
    }

}
